Vue快速入门
简介
MVVM响应式编程模型,避免直接操作DOM,降低DOM操作的复杂性
安装Vscode 安装nodejs
检测是否安装成功 cmd → node -v → npm -v
npm设置镜像[cmd]
C:\Users\Pluminary>npm config set registry https://registry.npmmirror.com
C:\Users\Pluminary>npm config ls
C:\Users\Pluminary>npm config get registry
在Vscode里的终端输入
PS C:\Users\Pluminary\Desktop\vue2> npm init -y
PS C:\Users\Pluminary\Desktop\vue2> npm install vue
Vue Chrome调试工具 Vue.js devtools 5.3.3 安装包及教程_vuedevtool.crx百度网盘-CSDN博客
简单案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--<div>{{name}}</div> 这个就没有被挂载-->
<div id="app">
<input type="text" v-model="num"> <!--在对话框里输入的时候改变下面的次数-->
<button v-on:click="num++">登录</button> <!--实现当点击按钮的时候num数值++-->
<button v-on:click="loginout()">登出</button>
<h1>{{name}}, 欢迎您,当前登录第{{num}}次,当前登录时间:{{nowDate()}}</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 1. new vue实例 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始的
new Vue({
el:"#app", // 挂载的模板
data(){ // 绑定的数据 把data对象中的所有属性 加到相应视图里
return{
name : "图灵学院",
num:1
}
},
methods: {
nowDate(){
return new Date().toLocaleDateString()
},
loginout(){
this.num--; //当调用实例时要加this
}
},
});
// 双向绑定:数据发生改变 视图也要随之改变;在谷歌浏览器的Vue调试中
// 指令:简化对Dom的频繁操作
// 方法:声明方法可以实现更复杂的操作,声明methods属性中
</script>
</body>
</html>
指令 v-text、v-html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-text="message"></div>{{message}}
<!-- {{}}在网络延迟情况下会出现暂时显示的情况 -->
<div v-html="message"></div>
</div>
</body>
<script>
// 1.实例Vue
var vm = new Vue({
el:'#app',
data:{
message: "<a href = '#'>Hello</a>"
},
})
// v-text 用于绑定数据,语法v-text="属性",会直接将值作为文本显示
// v-html 会将值进行编译再显示
</script>
</html>
指令 v-bind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.red{
background-color: red;
}
.yellow{
background-color: yellow;
}
</style>
</head>
<body>
<div id="app"> <!--:style="font-size: {{bigFont}}; 错误写法-->
<div v-bind:title="title" :class="red" :style="{fontSize:bigFont}">
鼠标悬停查看信息!
</div>
<div :class="{yellow:isyellow}">
<a :href="href" :style="{fontSize:bigFont}">图灵学院</a>
</div>
<div>
<img :src="src"/>
</div>
<div>
<button v-bind:disabled="disabled">禁用按钮</button>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
red:"red",
isyellow:true,
bigFont:"50px",
title: "您好,本网站可以学到更多的知识",
href: "https://www.pronhub.com/",
scr: '../Imooc_Cat.jpg',
disabled: true
}
})
// 绑定元素属性 -- v-bind
// 语法:v-bind:元素属性="vue的属性"
// 简写:v-bind:title 简写成 :title
/*
针对样式的特殊用法:
动态控制class是否添加 :class="{red:isred}"
语法 {red:isred} : {需要动态控制的class样式:vue的属性(需要是boolean类型)}
动态设置style的样式 :style="{fontSize:bigFont}"
语法 {fontSize: bigFont} : {css样式的驼峰命名方法:} font-size=fontSize
*/
</script>
</html>
指令 v-model
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
<label>年龄:</label>
<input v-model="age"/>
</div>
<div>当前输入的年龄是:{{age}}</div>
<button @click="add">加一岁</button> <!-- @click = v-on:click -->
<button @click="alertYear">弹出年龄</button>
<hr>
<label>课程:</label>
<select v-model="course">
<option value="javascript">javascript</option>
<option value="java">java</option>
<option value="c++">c++</option>
</select>
<div>
<input v-model="course" type="radio" name="course" value="javascript">javascript
<input v-model="course" type="radio" name="course" value="java">java
<input v-model="course" type="radio" name="course" value="c++">c++
</div>
<div>当前课程是:{{course}}</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
age:10,
course:'java'
},
methods: {
add(){
this.age++;
},
alertYear(){
alert(this.age)
}
}
})
//v-model 用于实现双向绑定 一般用在表单元素
</script>
</html>
指令 v-on
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="hello('hello')">hello</button>
<button @click="hello('world')">world</button>
<button @click="num++">数据:</button>{{num}}
<!-- 不让事件传播 禁止默认a标签事件
@click.stop 不让事件传播
@click.self 需要自己点击[不会参与传播]
@click.prevent 组织默认事件
@click.once 事件只会触发一次
-->
<div @click="hello(1)" style="background-color: red; width: 800px; height: 500px;padding: 50px;">
1
<div @click.stop="hello(2)" style="background-color: blue; width: 400px; height: 200px;padding: 50px;">
2
<a @click.stop.prevent="hello(3)" style="background-color: yellow; width: 200px; height: 100px; display: block;padding: 50px;" href="www.baidu.com">3</a>
</div>
</div>
<input v-on:keyup.enter="hello('enter')"> <!--键盘按回车触发--><br>
<input v-on:keyup.space="hello('enter')">
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
num: 0
},
methods: {
hello(str){
alert(str)
}
}
})
/*
v-on用于绑定事件
语法 v-on:事件名
简写方式 v-on:click => @click
只能调用vue中的函数和数据
*/
</script>
</html>
指令 v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
循环数组
<ul>
<li v-for="(item, index) in music">{{item.name}}---{{index+1}}</li>
</ul>
循环对象
<ul>
<li v-for="(item, index) in obj">{{item}}</li>
</ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
// 要循环的数组
music:[
{name: '青花瓷'},
{name: '阳光总在风雨后'},
{name: '十年'}
],
// 要循环的对象
obj:{
name: '句号',
age: 18,
sex: '男'
}
}
})
/*
v-for循环,可以循环数组和对象
v-for="(item, index) in intems
语法:v-for="(每次循环接收的变量, 当前循环的索引) in 需要循环的变量"
*/
</script>
</html>
指令 v-if 与 v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="vif=!vif">切换显示隐藏</button>
<div v-if="vif" style="background-color: red; width: 200px; height: 200px;">
v-if
</div>
<hr>
<button @click="vshow=!vshow">切换显示隐藏</button>
<div v-show="vshow" style="background-color: yellow; width: 200px; height: 200px;">
v-show
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
vif: true,
vshow: true
}
})
/*
v-if 和 v-show 用于控制元素显示隐藏
语法 v-if = "指定Boolean值" v-show一样
v-if 控制元素是否生成
v-show 控制元素是否显示隐藏
*/
</script>
</html>
指令 v-else 与 v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-if="number == 1">
A
</div>
<div v-else-if="number == 2">
B
</div>
<div v-else>
C
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data() {
return {
number: 1
}
},
})
</script>
</html>
计算属性和侦听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计算属性和侦听器</title>
</head>
<body>
<div id="app">
<!-- 实现一个购物车功能
1. 数据初始化处理
2. 选择商品数量:当商品数量超过库存做提示
3. 计算商品总价
-->
<ul>
<li v-for="(item, index) in car">
{{item.pname}} --- 商品价格:{{item.price}} --- 库存:{{item.stock}}
数量:<input type="number" v-model="item.num" style="width: 30px;"/>
</li>
<li><strong>总价:</strong>{{calcSum}}</li>
<!-- <li v-html="warn()"></li> -->
<li v-html="message"></li>
</ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
car:[
{pname:'IPhone 12',price:10000,stock:10,num:1},
{pname:'Mate40 pro',price:7000,stock:3,num:1},
],
message:"",
},
// methods:当方法中的数据发生改变,方法会自动调用 所以当数量增加时会自动计算总价
methods: {
// calcSum(){
// let sum=0;
// this.car.forEach(item => {
// sum+=item.price*item.num;
// });
// return sum;
// }
// warn(){
// let message="";
// this.car.forEach(item => {
// if(item.num>item.stock){
// message+=`${item.pname}的库存超出限制<br/>`
// }
// });
// return message;
// }
},
// 计算属性 上面就不加大括号 <li><strong>总价:</strong>{{calcSum}}</li>
computed:{
calcSum(){
let sum=0;
this.car.forEach(item => {
sum+=item.price*item.num;
});
return sum;
}
},
// 侦听器 专门用于侦听某些数据的变化,当数据发生变化会自动调节方法 不能像方法那样调用
watch:{
// 要侦听的数据
car:{
handler(newvalue,oldvalue){
this.message="";
this.car.forEach(item => {
if(item.num>item.stock){
this.message+=`${item.pname}的库存超出限制<br/>`
}
});
},
deep:true
},
//侦听message 基础类型的侦听 将侦听数据作为函数就可以了
message(newvalue,oldvalue){
console.info(newvalue,oldvalue)
}
}
});
/*
方法和计算属性的区别:
声明方式不一样,调用不一样方法要用"()", 计算属性调用不要加"()"
*/
/*
方法和侦听器的区别:
方法:方法中任意数据发生改变了就会自动调用方法
可以调用,进行返回值
侦听器:需要指定具体的侦听数据,只有被具体指定的侦听数据发生了改变才会触发
不能像方法那样去调用,而是靠vue自动触发 如果初始情况就数量就大于库存是不改变的
*/
</script>
</html>
过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>过滤器</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in userList">
姓名:{{user.name}}; 性别:{{user.gender==1?"男":"女"}}
{{user.gender | filterGender}}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data:{
userList:[
{id:1, name:'xushu', gender:1},
{id:2, name:'zhuge', gender:0}
]
},
//针对数据过滤的
methods:{
formateGender(gender){
if(gender==1){
return "~男"
}else{
return "~女"
}
}
},
filters:{
filterGender(gender){
if(gender==1){
return "!男"
}else{
return "!女"
}
}
}
})
</script>
</body>
</html>
Vue-组件化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>组件化</title>
</head>
<body>
<div id="app">
<!-- <div @click='num++'>{{num}}</div> -->
<!-- <xushu></xushu> -->
<xushu :num="numxx"></xushu> <!--传递属性--> <!--输出50-->
<app-xushu></app-xushu> <!--输出66-->
</div>
<div id="app2">
<!-- <div @click='num++'>{{num}}</div> -->
<!-- <xushu></xushu> -->
<xushu :num="numxx"></xushu> <!--传递属性--> <!--输出100-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
// 1.全局组件 在所有的Vue实例中使用
/*
1.1 命名:不要使用驼峰命名法 可以用中划线命名
1.2 模板:必须的
1.3 数据:一定要函数的方式声明
*/
Vue.component("xushu", {
template: `<div @click='num++'>{{num}}</div>`,
//1.在自己的字方法中声明
// data() {
// return {
// num:10
// }
// },
//2.在下方父方法中声明并传递过来
props: ["num"]
});
// 2.局部组件 //自己定义下面引用
const appXushu = {
template: `<div @click='num++'>{{num}}</div>`,
data() {
return {
num: 66
}
}
};
new Vue({
el: "#app",
data: {
numxx: 50
},
components: {
"app-xushu": appXushu
}
});
new Vue({
el: "#app2",
data: {
numxx: 100
}
});
</script>
</body>
</html>
生命周期和钩子函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<span id="name">{{name}}</span>
<button @click="updateName">更新</button>
<button @click="destroyInstance">销毁</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data:{
name: 'hello !'
},
methods: {
updateName(){
console.log('准备改名字啦!')
this.name = 'hello 图灵!'
},
destroyInstance(){
console.log('销毁实例')
vm.$destroy()
}
}
})
</script>
</html>
vue-router
npm install vue-router@3
npm install vue-router@3 --legacy-peer-deps
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-- 1.安装vue-router路由
2.引入vue-router文件
3.根据不同url连接到不同的页面,需要使用模板实现,将模板绑定对应的路由地址
-->
<body>
<div id="app">
<nav>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
</nav>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.js"></script>
<script>
// 定义组件:原本应该是在外面定义HomeComponent.vue [创建一些组件]
const HomeComponent = {
template: `<div><h1>Home</h1><p>Welcome to the Home page!</p></div>`
};
// 定义组件:原本应该是在外面定义AboutComponent.vue [创建一些组件]
const AboutComponent = {
template: `<div><h1>About</h1><p>Learn more about us on this page.</p></div>`
};
// 定义路由:原本应该是外面定义router.js文件来定义路由。
const routes = [
{ path: '/', component: HomeComponent },
{ path: '/about', component: AboutComponent }
];
// 创建路由实例
const router = new VueRouter({
routes
});
// 创建并挂载根实例
const app = new Vue({
router// 挂载路由
}).$mount('#app');
</script>
</body>
</html>
axios
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue with Axios Example</title>
</head>
<body>
<div id="app">
<h1>Data from API</h1>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
<!-- 使用 Vue 的 v-for 指令遍历 posts 数组,并生成列表项,每个列表项显示 post.title。 -->
</ul>
</div>
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入 Axios -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 创建 Vue 实例
let vm = new Vue({
el: "#app", // Vue 实例绑定到 HTML 中的 id="app" 的元素
data: {
posts: [] // 初始化一个空数组用于存储从 API 获取的数据
},
created() {
// Vue 实例创建时调用的生命周期钩子
axios.get('https://jsonplaceholder.typicode.com/posts') // 使用 Axios 发送 GET 请求
.then(response => { // 请求成功后的处理
this.posts = response.data; // 将响应数据赋值给 posts 数组
})
.catch(error => { // 请求失败后的处理
console.error('Error fetching data:', error); // 输出错误信息到控制台
});
}
});
</script>
</body>
</html>
安装脚手架
CLI文档,开箱即用!
cmd全局安装:
npm install -g @vue/cli 或者
npm install -g @vue/cli-init
去想要的文件夹里面:C:\Users\Pluminary\Desktop\vue_cli>vue init webpack tuling
vue init webpack 项目名
? Project name tuling
? Project description A Vue.js project
? Author pcy
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No //严格检验Javascript语法的
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
完成后需要开启:
cd tuling
npm run dev
DONE Compiled successfully in 1780ms 18:41:21
I Your application is running here: http://localhost:8080
运用element-ui创建一个简易的登录界面
<template>
<div class="hello-world">
<h1>{{ message }}</h1>
<el-button type="primary" @click="showAlert">Click Me</el-button>
</div>
<div class="app">
<h3>{{passage}}</h3>
<h4>{{getVal()}}</h4>
</div>
<!-- 使用Element UI的Table组件展示empList -->
<el-table :data="empList" style="width: 100%">
<el-table-column prop="name" label="Name" width="180"></el-table-column>
<el-table-column prop="salary" label="Salary" width="180"></el-table-column>
</el-table>
<!-- 登录表单 -->
<el-form ref="loginForm" :model="loginForm" class="loginForm" label-width="80px">
<h2 class="loginTitle">人事后台管理系统</h2>
<el-form-item label="用户名" prop="username">
<el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input v-model="loginForm.code" placeholder="请输入验证码"></el-input>
</el-form-item>
<el-form-item style="width:100%;">
<el-button type="primary" @click="handleLogin">登录</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
name: 'app',
data(){
return{
passage: 'Oh?',
message: 'Hello World!',
empList:[
{ name: 'Peter', salary: '20000' },
{ name: 'Mike', salary: '16000' },
{ name: 'Tom', salary: '17000' }
],
loginForm:{
username:'',
password:'',
code:''
}
}
},
methods: {
showAlert() {
this.$message({
message: 'Hello from Element UI!',
type: 'success'
});
},
getVal:function(){
return "getVal的方法";
},
handleLogin() {
this.$message({
message: `登录成功,用户名: ${this.loginForm.username}`,
type: 'success'
});
}
}
}
</script>
<style scoped>
.hello-world {
text-align: center;
margin-top: 20px;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
.app {
margin-top: 30px;
}
</style>
在Vue项目中,Element UI需要正确引入CSS样式和JavaScript文件才能正常工作。如果你没有一个HTML模板文件(例如index.html),而是在Vue组件中直接编写代码,你需要通过一些方式来确保Element UI的样式和脚本被正确加载。
// 1. 创建index.html文件:
这个index.html文件通常放在public文件夹下,是你Vue应用的入口文件。Vue CLI自动生成的项目通常会有这个文件。
// 2. 为什么需要这个HTML文件?
这个index.html文件是Vue CLI或手动设置的Vue项目的入口页面。当你运行npm run serve时,Vue CLI会将所有内容注入到<div id="app"></div>中,这个HTML文件是项目的基本框架。
Element UI的CSS和JS资源:需要在HTML文件的<head>中引入Element UI的样式文件(CSS)和在<body>中引入JS库,这样才能确保Element UI组件在你的Vue组件中正确渲染和运行。
// 3. 直接在Vue组件中引入:
如果你不想使用外部HTML文件,Vue项目中可以直接在main.js中引入Element UI的样式和组件:
/*
// main.js
import Vue from 'vue';
import App from './App.vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false;
Vue.use(ElementUI);
new Vue({
render: h => h(App),
}).$mount('#app');
*/